/*
 * Clock.c
 *
 * Created: 14.01.2013 14:31:42
 *  Author: saenko
 */ 

#include <avr/io.h>
#include "spi.h"
#include "twi.h"
#include "max7219.h"
#include "ds3232.h"

#define	MAIN_MODE 0
#define SET_HOUR_MODE 1
#define SET_MIN_MODE 2

volatile unsigned char ds3232_int;
volatile unsigned char button_int;

volatile unsigned char hours;
volatile unsigned char minutes;

volatile unsigned char key_pressed;

volatile unsigned char status;

volatile unsigned char half_sec;

volatile unsigned char blink_hour;

volatile unsigned blink_min;

volatile blink_enable = 1;

ISR(INT0_vect)
{
	
	unsigned char temp = PIND & (1<<PD2);
	if(temp>0) ds3232_int = 1;
	else
		if(blink_enable) half_sec = 1;
	
}

ISR(PCINT1_vect)
{
	button_int = 1;
	key_pressed = PINC & 0b00001111;
	PCICR = 0;
	TCCR1B = (1<<CS01)|(1<<CS00);
}

ISR(TIMER1_OVF_vect)
{
	key_pressed = PINC & 0b00001111;

	TCCR1B = 0;
	PCICR = (1<<PCIE1);	
	
	if(key_pressed==((0b00001011)|(0b00001101)))
	{
		TCCR1B = (1<<CS01)|(1<<CS00);
		blink_enable = 0;
	}
	else
	{
		blink_enable = 1;		

	}		
}

int main(void)
{
	DDRD = 0b10000000;
	PORTD = (1<<PD2);
	
	DDRC = 0b00000000;
	PORTC = 0b00001111;
	
	PCICR = (1<<PCIE1);
	PCMSK1 = 0b00001111;
	
//	TCCR1B = (1<<CS01)|(1<<CS00);
	TIMSK1 = (1<<TOIE1);

	
	spi_init();
	twi_init(0b01111111);

	
    max7219_cmd(0x09,0x0F);	
	max7219_cmd(0x0B,0x04);	
    max7219_cmd(0x0C,0x01);
	
	/*  max7219_cmd(0x01,0x01);
	    max7219_cmd(0x02,0x02);
		max7219_cmd(0x03,0x03);
		max7219_cmd(0x04,0x04);	*/
   //	max7219_test();	
	
	
	
	sei();
	
	
	
	hours = 0x09;
	minutes = 0x37;
	
    ad3232_set_time(hours,minutes);
	
	ad3232_init();	
	
//	ad3232_get_time();
	
	half_sec= 0;
	
    while(1)
    {
		if(ds3232_int)
		{
			ds3232_int = 0;
			ad3232_get_time();
		}
		
		if(twi_flags.receive_end)
		{
			twi_flags.receive_end = 0;
			if(status == MAIN_MODE)
			{
				hours = twi_buf_rx[1];
				minutes = twi_buf_rx[0];				
			}

			max7219_out_time(hours,minutes);			
		}
		
		if(half_sec)
		{
			half_sec= 0;
			if(blink_hour) max7219_out_time(0xFF,minutes);
			if(blink_min) max7219_out_time(hours,0xFF);
		}
		
		switch(key_pressed)
		{
			case 0b00000111:
				switch(status)
				{
				case MAIN_MODE: 
					status = SET_HOUR_MODE;
					blink_hour = 1;
					blink_min = 0;
					key_pressed = 0;
				break;
				case SET_HOUR_MODE:
					status = SET_MIN_MODE;
					blink_hour = 0;
					blink_min = 1;
					key_pressed = 0;
				break;
				case SET_MIN_MODE:
					status = MAIN_MODE;
					blink_hour = 0;
					blink_min = 0;
					ad3232_set_time(hours,minutes);
					key_pressed = 0;
				break;
				}
			break;
				
			case 0b00001011:
				switch(status)
				{
				case SET_HOUR_MODE:
					switch(++hours)
					{
					case 0x0A: hours = 0x10; break;
					case 0x1A: hours = 0x20; break;
					case 0x24: hours = 0x00; break;	
					}
					max7219_out_time(hours,minutes);
					key_pressed = 0;
				break;
					
				case SET_MIN_MODE:
					switch(++minutes)
					{
					case 0x0A: minutes = 0x10; break;	
					case 0x1A: minutes = 0x20; break;
					case 0x2A: minutes = 0x30; break;
					case 0x3A: minutes = 0x40; break;
					case 0x4A: minutes = 0x50; break;
					case 0x5A: minutes = 0x00; break;
					}
					max7219_out_time(hours,minutes);
					key_pressed = 0;
				break;	
				}
				TCNT1 = 0b0111111111111111;
				half_sec = 0;
			break;
				
			case 0b00001101:
				switch(status)
				{
					case SET_HOUR_MODE:
					switch(--hours)
					{
						case 0xFF: hours = 0x23; break;
						case 0x1F: hours = 0x19; break;
						case 0x0F: hours = 0x09; break;
					}
					max7219_out_time(hours,minutes);
					key_pressed = 0;
					break;
								
					case SET_MIN_MODE:
					switch(++minutes)
					{
						case 0x0A: minutes = 0x10; break;
						case 0x1A: minutes = 0x20; break;
						case 0x2A: minutes = 0x30; break;
						case 0x3A: minutes = 0x40; break;
						case 0x4A: minutes = 0x50; break;
						case 0x5A: minutes = 0x00; break;
					}
					max7219_out_time(hours,minutes);
					key_pressed = 0;
					break;
				}
				TCNT1 = 0b0111111111111111;
				half_sec = 0;
				break;
			
		}
		

			
    }
}